<template>
  <div>
    <base-modal :width="modAlProps.width" :isVisible="isVisible" :title="modAlProps.title" :isCancleBtn="isCancleBtn"
      @handleOk="handleOk" @handleCancle="handleCancle" class="site_modal">
      <template v-slot:body>
        <div class="cropper-content">
          <div class="cropper-wrap">
            <VueCropper ref="cropper" :img="option.src" :info="option.info" :full="option.full"
              :outputSize="option.outputSize" :canMove="option.canMove" :canMoveBox="option.canMoveBox"
              :centerBox="option.centerBox" :fixedBox="option.fixedBox" :fixed="option.fixed"
              :fixedNumber="option.fixedNumber" :original="option.original" :autoCrop="option.autoCrop"
              :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :high="option.high"
              @realTime="realTime" />
            <div class="proportion">
              <a-tabs v-model:activeKey="tabActive">
                <a-tab-pane key="1" tab="比例">
                  <div class="proportion_choice">
                    <div :class="cuttingImgId == item.id ? 'proportion_lables' : 'proportion_lable'
                      " v-for="(item, index) in radioList" :key="index" @click="cuttingImg(item)">
                      <!-- <span
                        :class="item.lable == '1:1' ? 'proportion_span' : item.lable == '3:4' ? 'tf_span' : item.lable == '2:3' ? 'tt_span' : item.lable == '16:9' ? 'sn_span' : item.lable == '16:10' ? 'st_span' : ''"></span> -->
                      <div>
                        <div>
                          {{
                            cuttingImgName == "自定义" && cuttingImgId == item.id
                            ? ""
                            : item.lable
                          }}
                        </div>
                        <div v-if="cuttingImgName == '自定义' && cuttingImgId == item.id" class="custom">
                          <a-input-number v-model="inputVal[0]" class="inputValue" :min="1" @blur="wdithVal" />
                          <span>:</span>
                          <a-input-number v-model="inputVal[1]" class="inputValue" :min="1" @blur="heightVal" />
                        </div>
                      </div>
                    </div>
                  </div>
                </a-tab-pane>
                <a-tab-pane key="2" tab="尺寸">
                  <span>宽度:</span>
                  <a-input-number v-model:value="picWidth" class="inputValue" :min="1" :max="naturalWidth"
                    @change="dimensionsWidth" />
                  <span>高度:</span>
                  <a-input-number v-model:value="picHeight" class="inputValue" :min="1" :max="naturalHeight"
                    @change="dimensionsHeight" />
                  <div class="inputValue">
                    <a-switch v-model:checked="isLock" @change="lockChange" />
                    <span>锁定宽高比例</span>
                  </div>
                </a-tab-pane>
              </a-tabs>
            </div>
          </div>
          <div class="show-preview" :style="{ width: previews.w + 'px', height: previews.h + 'px' }">
            <div :style="previews.div">
              <img :src="previews.url" :style="previews.img" />
            </div>
          </div>
        </div>
      </template>
    </base-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, onMounted, nextTick } from "vue";
import baseModal from "@/components/modal/baseModal.vue";
import "vue-cropper/dist/index.css";
import { VueCropper } from "vue-cropper";
import { scrollType, modeProp } from "@/type.d";
// import { nextTick } from "process";
//interface
interface Options {
  [propName: string | number]: any;
}
// porps
const props = defineProps({
  isVisible: {
    type: Boolean,
    default: false,
  },
  src: {
    type: String,
    default: "",
  },
  name: {
    type: String,
    default: "1111.png",
  },
  id: {
    type: String,
    default: "111",
  },
});
//data
//模态框数据
const modAlProps: modeProp = reactive({
  width: "2600",
  title: "图片裁剪",
});
//模态框button按钮个数和文案修改
const isVisible = ref<Boolean>(false); // 模态框是否可见
let buttons = ref<Options[]>([]);
let isCancleBtn = ref<Boolean>(true);
const isLock = ref<Boolean>(false);
//裁剪插件
const cropper = ref(); //裁剪的ref
const option = reactive<Options>({
  src: props.src,
  autoCropWidth: 100,
  autoCropHeight: 100,
  info: true, // 裁剪框的大小信息
  outputSize: 1, // 裁剪生成图片的质量
  outputType: "png", // 输出图片格式
  canScale: true, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  fixedBox: false, // 固定截图框大小 不允许改变
  fixed: false, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1],
  full: true, // 是否输出原图比例的截图
  canMove: true, // 能否拖动图片
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  high: true, // 是否根据dpr生成适合屏幕的高清图片
});
const radioList = ref<Options[]>([
  { id: 11, lable: "自由", arr: [1, 1] },
  { id: 12, lable: "原图", arr: [1, 1] },
  { id: 1, lable: "1:1", arr: [1, 1] },
  { id: 2, lable: "5:3", arr: [5, 3] },
  { id: 3, lable: "3:4", arr: [3, 4] },
  { id: 4, lable: "4:3", arr: [4, 3] },
  { id: 5, lable: "2:3", arr: [2, 3] },
  { id: 6, lable: "3:2", arr: [3, 2] },
  { id: 7, lable: "16:9", arr: [16, 9] },
  { id: 8, lable: "9:16", arr: [9, 16] },
  { id: 9, lable: "16:10", arr: [16, 10] },
  { id: 10, lable: "10:16", arr: [10, 16] },
]);
const inputVal = ref<number[]>([]);
const picWidth = ref<string | number>();
const picHeight = ref<string | number>();
const previews = ref<Options>({});
const cuttingImgId = ref<string | number>("");
const cuttingImgName = ref<string | number>("");
// tab
const tabActive = ref<string | number>("1");
const naturalHeight = ref<string | number>(0);
const naturalWidth = ref<string | number>(0);

// wacth
watch(
  () => props.src,
  (newVal, oldVal) => {
    if (newVal != oldVal) {
      option.src = newVal;
      getImageNaturalWH(newVal); //
    } else {
    }
  }
);
watch(
  () => props.isVisible,
  (newVal, oldVal) => {
    if (newVal != oldVal) {
      isVisible.value = newVal;
    }
  }
);
//method
// 实时预览函数
const realTime = (data: Options) => {
  previews.value = data;
};
// 选择剪切比例
const cuttingImg = (val: Options) => {
  cuttingImgId.value = val.id;
  cuttingImgName.value = val.lable;
  if (val.lable != "自定义") {
    let array: Options[] = radioList.value.filter((item) => item.lable == val.lable);
    if (array.length) {
      array.forEach((item) => {
        inputVal.value = item.arr;
      });
    }
  } else {
    radioList.value.forEach((item) => {
      if (val.lable == "自定义" && item.id == 7) {
        item.arr = inputVal.value;
      }
    });
  }
  option.fixedNumber = val.arr;
  console.log(option.fixedNumber, "option.fixedNumber");
  let cropHeight = parseInt(`${option.autoCropWidth * (val.arr[1] / val.arr[0])}`);
  nextTick(() => {
    cropper.value.changeCrop(option.autoCropWidth, cropHeight);
  });
};
const wdithVal = (e: Options) => {
  inputVal.value[0] = e.target.value;
  option.fixedNumber = inputVal.value;
  let cropHeight = parseInt(
    `${option.autoCropWidth * (inputVal.value[1] / inputVal.value[0])}`
  );
  cropper.value.changeCrop(option.autoCropWidth, cropHeight);
};
const heightVal = (e: Options) => {
  inputVal.value[1] = e.target.value;
  option.fixedNumber = inputVal.value;
  let cropHeight = parseInt(
    `${option.autoCropWidth * (inputVal.value[1] / inputVal.value[0])}`
  );
  cropper.value.changeCrop(option.autoCropWidth, cropHeight);
};
const dimensionsWidth = (e: number) => {
  picWidth.value = e;
  if (isLock.value) {
    let cropHeight = parseInt(
      `${picWidth.value * (inputVal.value[1] / inputVal.value[0])}`
    );
    picHeight.value = Number(cropHeight);
    option.autoCropWidth = picWidth.value;
    option.autoCropHeight = cropHeight;
  } else {
    picWidth.value = e;
    option.autoCropWidth = picWidth.value;
  }
};
const dimensionsHeight = (e: number) => {
  picHeight.value = e;
  if (isLock.value) {
    let cropWidth = parseInt(
      `${picHeight.value * (inputVal.value[0] / inputVal.value[1])}`
    );
    picWidth.value = cropWidth;
    option.autoCropWidth = cropWidth;
    option.autoCropHeight = picHeight.value;
  } else {
    picHeight.value = e;
    option.autoCropHeight = picHeight.value;
  }
};
const lockChange = (isLocks: boolean) => {
  if (isLocks) {
    if (picWidth.value) {
      dimensionsWidth(option.autoCropWidth);
    } else if (picHeight.value) {
      dimensionsHeight(option.autoCropHeight);
    }
  }
};
const getImageNaturalWH = (src: string) => {
  // 获取图片原始宽高;
  const url = src;
  if (url) {
    var img = new Image();
    img.src = url;
    img.onload = function () {
      naturalHeight.value = img.naturalHeight;
      naturalWidth.value = img.naturalWidth;
      radioList.value[1].arr = [naturalWidth.value, naturalHeight.value];
      option.autoCropWidth = img.naturalWidth;
      option.autoCropHeight = img.naturalHeight;
      inputVal.value[0] = option.autoCropWidth;
      inputVal.value[1] = option.autoCropHeight;
    };
  }
};
const emits = defineEmits(["handleOk", "handleCancle"]);
//type
const handleOk = (e: MouseEvent) => {
  // cropper.value.getCropBlob((data: any) => {
  //   let files = new File(data, props.name, {
  //     type: "image/png",
  //     lastModified: Date.now(),
  //   });
  //   console.log(files, "files");
  // });
  cropper.value.getCropBlob((data: any) => {
    console.log("获取截图的 blob 数据:", data);
    // 下面是将blob转为formData
    let formData = new FormData();
    formData.append("file", data, new Date().getTime() + ".jpg");
    // 下面是将blob转换为file
    data.lastModifiedDate = new Date(); // 文件最后的修改日期
    let files = new File([data], props.name, {
      type: data.type,
      lastModified: Date.now(),
    });
    emits("handleOk", files, props.id, e);
  });
};

const handleCancle = (e: MouseEvent) => {
  emits("handleCancle", e);
};
//onMounted
onMounted(() => {
  getImageNaturalWH(props.src); //
});
</script>

<style lang="less" scoped>
.cropper-content {
  .cropper-wrap {
    width: 100%;
    height: 300px;
    display: flex;

    .vue-cropper {
      flex: 1;
    }

    .proportion {
      margin-left: 24px;
      width: 132px;

      .title {
        font-size: 16px;
        color: #333;
        margin-bottom: 24px;
      }

      .proportion_choice {
        // display: flex;
        // flex-wrap: wrap;
        height: 224px;
        overflow-y: auto;
        margin-top: 24px;
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        grid-template-rows: repeat(6, 1fr);
        width: 132px;
        grid-gap: 0px;

        .proportion_lable {
          width: 60px;
          height: 32px;
          border: 1px solid rgba(0, 0, 0, 0.15);
          border-radius: 2px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 14px;
          color: rgba(0, 0, 0, 0.85);
        }

        .proportion_lables {
          width: 60px;
          height: 32px;
          border: 1px solid var(--theme_button_active_bg_color, #1d39c4);
          border-radius: 2px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 14px;
          font-weight: 500;
          color: var(--theme_button_active_bg_color, #1d39c4);

          .custom {
            display: flex;
            align-items: center;

            span {
              margin: 0 6px;
            }

            .el-input__inner {
              border: none;
              border-bottom: 1px solid #1ec6df;
              border-radius: 0;
              text-align: center;
              color: #999999;
              padding: 0;
            }

            .el-input--mini {
              font-size: 16px;
              width: 32px;
            }
          }

          .proportion_span {
            width: 24px;
            height: 24px;
            display: inline-block;
            border-radius: 2px;
            margin-right: 10px;
            border: 1px solid #1ec6df;
          }
        }

        .proportion_lable:hover {
          border: 1px solid var(--theme_text_hightlight_color, #2f54eb);
          color: var(--theme_text_hightlight_color, #2f54eb);
          cursor: pointer;

          // .proportion_span {
          //   border: 1px solid #1EC6DF;
          // }
        }
      }
    }
  }

  .show-preview {
    border: 1px solid #e8e8e8;
    margin-top: 20px;
    overflow: hidden;
  }

  .inputValue {
    margin-top: 24px;
  }
}
</style>
<style>
.vue-cropper {
  height: 300px !important;
}
</style>
